package com.ddone.demo.mapper;

import com.ddone.demo.bean.Emp;
import com.ddone.demo.bean.TestStrPk;
import com.ddone.demo.utils.MybatisUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author ddone
 * @date 2024/3/17-20:31
 */
public class MapperTest {
    private SqlSession sqlSession;
    /**
     * 使用ibatis方式进行数据库查询！ mybatis 2.0之前方式
     */
    @Before
    public void init() throws IOException {
        // 1.读取mybatis核心配置文件
        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        // 2.创建一个SqlSessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
        // 3.创建一个sqlSession [具体进行数据库交互]
        sqlSession = sessionFactory.openSession();
    }
    @After
    public void destroy(){
        sqlSession.close();
    }
    @Test
    public void testQuery() throws IOException {
        // 1. 读取配置文件
        //Resources: org.ibatis 工具，用于读取配置文件！
        //参数： 填配置文件名称
        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        // 2.创建一个SqlSessionFactoryBuilder()去获取sessionFactory
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(stream);
        // 3.创建一个SqlSession对象，他是真正进行数据库操作的对象！
        SqlSession sqlSession = sessionFactory.openSession();
        // 4.进行数据库操作 sqlSession 提供了curd方法
            // sqlSession.selectOne();  查询单个对象！
            // sqlSession.selectList(); 查询集合对象！
            // sqlSession.insert();     数据库插入
            // sqlSession.update();     数据更新
            // sqlSession.delete();     数据删除
        /*
         * 参数1：<select id="selectEmpById"  id值
         * 参数2：传入的参数
         * return Object 查询的返回结果
         */
        Emp emp = sqlSession.selectOne("selectEmpById", 1);
        System.out.println("emp = " + emp);
        // 5. 释放资源
        sqlSession.close();

    }
    @Test
    public void testQueryList(){
        //1.调用方法进行查询
        /*
         * 参数1：String statementId
         *        mapper 增删改查标签的标识
         *        语法1： 标签id  【名】
         *        语法2： Mappernamespace.标签id 【姓名】
         * 参数2：Object parameter
         *        传入的参数，如果没有，直接不写！
         * 返回结果： List<Object>
         */
        List<Emp> empList = sqlSession.selectList("com.ddone.demo.mybatis.bean.Emp.selectAll");
        System.out.println("empList = " + empList);
    }
    /*
     * TODO:常见错误
     *   错误1： statement标识错误
     *          Mapped Statements collection does not contain value for
     *   错误2： mapper.xml文件忘配置到mybatis核心配置文件了
     *         Mapped Statements collection does not contain value for
     *   错误3：配置mapperxml文件，对应路径错误
     *         Cause: java.io.IOException: Could not find resource
     */

    /**
     * DML语句执行数据不更新问题！
     *    mybatis配置了事务的自动开启！
     *    每次进行dml语句操作，需要提交事务，方可更新数据库！
     * TODO:解决方案
     *    1.手动事务提交  sqlSession.commit();
     *    2.开启自动事务提交 factory.openSession(true);
     *
     * @throws IOException
     */
    @Test
    public void testInsert() throws IOException{
        Emp emp = Emp.builder()
                .empName("王大花")
                .empSalary(30000.11)
                .build();
        // 调用sqlSession的 insert delete update 都是返回int 类型，是影响的行数！
        int insertRows = sqlSession.insert("com.ddone.demo.mybatis.bean.Emp.insertEmp", emp);
        sqlSession.commit();
        System.out.println("insertRows = " + insertRows);
    }

    @Test
    public void testDelete(){
        SqlSession sqlSession = MybatisUtil.openAutoSession();
        int rows = sqlSession.delete("com.ddone.demo.mybatis.bean.Emp.deleteEmpById", 3);
        System.out.println("rows = " + rows);
    }

    @Test
    public void testQueryMapper(){
        //1.获取session即可
        SqlSession sqlSession = MybatisUtil.openSession();
        // 2.获取mapper接口的实现类
        //Mapper接口 找 中介！ 动态代理！
        // 接口 =  实现类  多态技术
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        // 3.进行数据库操作
        Emp emp = mapper.selectEmpById(4);
        System.out.println("emp = " + emp);
        // 4. 关闭链接
        sqlSession.close();

    }

    @Test
    public void testQueryParam() {
        //1.获取session与Mapper
        SqlSession sqlSession = MybatisUtil.openSession();
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> empList = mapper.queryByParam("emp_id", "4");
        System.out.println("empList = " + empList);
    }

    @Test
    public void testInsertMapper(){
        EmpMapper mapper = MybatisUtil.openAutoSession().getMapper(EmpMapper.class);
        Emp emp = Emp.builder().empName("李二狗").empSalary(2000.10).build();
        int rows= mapper.insertEmp(emp);
        System.out.println("rows = " + rows);
    }

    @Test
    public void testInsertMap(){
        EmpMapper mapper = MybatisUtil.openAutoSession().getMapper(EmpMapper.class);
        HashMap<String, Object> map = new HashMap<String, Object>() {{
            put("name","xxyy11");
            put("salary",2000.19);
        }};
        int rows = mapper.insertMap(map);
        System.out.println("rows = " + rows);
    }

    @Test
    public void testInsertReturnId(){
        EmpMapper mapper = MybatisUtil.openAutoSession().getMapper(EmpMapper.class);
        Emp emp = Emp.builder()
                .empName("张铁牛")
                .empSalary(30000.11)
                .build();
        System.out.println("emp = " + emp);
        int rows = mapper.insertEmpReturnId(emp);
        System.out.println("emp = " + emp);

    }

    @Test
    public void testReturnStringAndDouble(){
        EmpMapper mapper = MybatisUtil.openAutoSession().getMapper(EmpMapper.class);
        String name = mapper.queryNameById(5);
        Double salary = mapper.querySalaryById(5);
        System.out.println("name = " + name);
        System.out.println("salary = " + salary);
    }

    /**
     * TODO 手动维护! 不存在主键回显问题 过程比较繁琐
     *
     */
    @Test
    public void testInsertReturnStrId(){
        TestStrPkMapper mapper = MybatisUtil.openAutoSession().getMapper(TestStrPkMapper.class);
        String uuId = UUID.randomUUID().toString().replaceAll("-", "");
        TestStrPk testStrPk = TestStrPk.builder().id(uuId).name("王打哈").build();
        int rows = mapper.insert(testStrPk);
    }

    /**
     * 交给Mybatis维护
     */
    @Test
    public void testInsertReturnStrId2(){
        TestStrPkMapper mapper = MybatisUtil.openAutoSession().getMapper(TestStrPkMapper.class);
        int rows = mapper.insertReturnPK(TestStrPk.builder().name("主键回显").build());
        System.out.println("rows = " + rows);
    }
}